package com.zjsru.plan2025.oneday;

import java.util.Arrays;

/**
 * 2595. 奇偶位数
 *
 * @Author: cookLee
 * @Date: 2025-02-20
 */
public class EvenOddBit {

    /**
     * 主
     * \
     * 输入：n = 50
     * 输出：[1,2]
     * 解释：
     * 50 的二进制表示是 110010。
     * 在下标 1，4，5 对应的值为 1。
     * \
     * 输入：n = 2
     * 输出：[0,1]
     * 解释：
     * 2 的二进制表示是 10。
     * 只有下标 1 对应的值为 1。
     * \
     *
     * @param args args
     */
    public static void main(String[] args) {
        EvenOddBit evenOddBit = new EvenOddBit();
        int n = 50;
        System.out.println(Arrays.toString(evenOddBit.evenOddBit(n)));
    }

    /**
     * 暴力
     *
     * @param n n
     * @return {@link int[]}
     */
    public int[] evenOddBit(int n) {
        String binary = Integer.toBinaryString(n);
        int len = binary.length();
        int even = 0;
        int odd = 0;
        //二进制下标由右到左,第一位即使从右第一位开始计算,第一个下标默认为false表示偶数位
        boolean isOdd = false;
        for (int i = len - 1; i >= 0; i--) {
            if (isOdd) {
                isOdd = false;
                if (binary.charAt(i) == '1') {
                    odd++;
                }
            } else {
                isOdd = true;
                if (binary.charAt(i) == '1') {
                    even++;
                }
            }
        }
        return new int[]{even, odd};
    }

    /**
     * 位运算
     *
     * @param n n
     * @return {@link int[]}
     */
    public int[] evenOddBit2(int n) {
        int[] ans = new int[2];
        for (int i = 0; n > 0; n >>= 1) {
            ans[i] += n & 1;
            // 切换奇偶
            i ^= 1;
        }
        return ans;
    }

    /**
     * 利用位掩码0x55555555（二进制0101⋯01），与n计算 AND，即可取出所有偶数下标比特，然后用库函数统计其中1的个数。
     * <p>
     * 把0x55555555取反（二进制1010⋯10），与n计算 AND，即可取出所有奇数下标比特，然后用库函数统计其中1的个数。
     *
     * @param n n
     * @return {@link int[]}
     */
    public int[] evenOddBit3(int n) {
        final int MASK = 0x55555555;
        return new int[]{Integer.bitCount(n & MASK), Integer.bitCount(n & ~MASK)};
    }

}
